//
// Created by Tony on 2024/7/24.
//

#include "Stack.h"
#include "Frame.h"
#include <stdexcept>

namespace RtData {

using std::runtime_error;

Stack::Stack(uint32_t maxSize) : mMaxSize(maxSize), mSize(0), mPC(0) {}

void Stack::push(const shared_ptr<Frame>& frame) {
    if (mSize >= mMaxSize) {
        throw runtime_error("stack overflow"); // TODO throw to tvm
    }

    if (mTopFrame != nullptr) {
        frame->setLower(mTopFrame);
    }
    mTopFrame = frame;
    mSize++;
}

std::shared_ptr<Frame> Stack::pop() {
    if (mTopFrame == nullptr) {
        throw runtime_error("stack is empty"); // TODO throw to tvm
    }

    auto ret = mTopFrame;
    mTopFrame = ret->getLower();
    ret->setLower(nullptr);
    mSize--;

    return ret;
}

std::shared_ptr<Frame> Stack::top() {
    if (mTopFrame == nullptr) {
        throw runtime_error("stack is empty"); // TODO throw to tvm
    }
    return mTopFrame;
}

bool Stack::isEmpty() { return mTopFrame == nullptr; }

} // namespace RtData